package com.kai.steering.data.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.kai.steering.common.vo.Result;
import com.kai.steering.common.web.vo.ReturnCodeExt;
import com.kai.steering.data.service.databus.enums.UsableEnum;
import com.kai.steering.data.service.entity.domainObject.KnowledgeDO;
import com.kai.steering.data.service.entity.dto.KnowledgeQueryDTO;
import com.kai.steering.data.service.entity.po.Knowledge;
import com.kai.steering.data.service.entity.vo.KnowledgeVO;
import com.kai.steering.data.service.mapper.KnowledgeMapper;
import com.kai.steering.data.service.service.KnowledgeService;
import com.kai.steering.common.web.service.impl.BaseServiceImpl;
import com.kai.steering.common.vo.Page;

import com.kai.steering.data.service.util.EqualsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;

/**
 * <pre>
 * 知识点 服务实现类
 * </pre>
 *
 * @author kai
 * @since 2022-02-23
 */
@Slf4j
@Service
public class KnowledgeServiceImpl extends BaseServiceImpl<KnowledgeMapper, Knowledge> implements KnowledgeService {

    @Autowired
    private KnowledgeMapper knowledgeMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveKnowledge(KnowledgeDO knowledgeDO) {
        /**
         * 校验参数
         */
        //id
        if (!StrUtil.isEmpty(knowledgeDO.getKnowledgeId())) {
            knowledgeDO.setKnowledgeId(null);
        }
        //name
        KnowledgeDO oldKnowledge = getKnowledgeByName(knowledgeDO.getKnowledgeName());
        if (oldKnowledge == null || StringUtils.isEmpty(oldKnowledge.getKnowledgeId())) {
            throw ReturnCodeExt.DAO_EXCEPTION.getException("重名");
        }

        /**
         * 构建对象
         */
        Knowledge knowledge = new Knowledge(knowledgeDO);
        boolean save = super.save(knowledge);
        knowledgeDO = knowledgeDO.converKnowledgeDO(knowledge);
        return save;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateKnowledge(Serializable id, KnowledgeDO knowledgeDO) {
        /**
         * 参数检查
         */
        //id
        KnowledgeDO oldKnowledge = getKnowledgeById(id.toString());

        if (oldKnowledge == null || StringUtils.isEmpty(oldKnowledge.getKnowledgeId())) {
            throw ReturnCodeExt.DAO_EXCEPTION.getException("id不存在");
        }
        //name
        KnowledgeDO oldKnowledgeByName = getKnowledgeByName(knowledgeDO.getKnowledgeName());
        if (oldKnowledgeByName == null || StringUtils.isEmpty(oldKnowledgeByName.getKnowledgeId())) {
            throw ReturnCodeExt.DAO_EXCEPTION.getException("重名");
        }
        /**
         * 构建对象
         */
        Knowledge knowledge = new Knowledge(knowledgeDO);
        knowledge.setKnowledgeId(id.toString());
        knowledge.setCreationDate(new Date());
        boolean b = super.updateById(knowledge);
        knowledgeDO.converKnowledgeDO(knowledge);
        return b;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteKnowledge(Serializable id) {
        /**
         * 参数检查
         */
        //id
        KnowledgeDO oldKnowledge = getKnowledgeById(id.toString());

        if (oldKnowledge == null || StringUtils.isEmpty(oldKnowledge.getKnowledgeId())) {
            throw ReturnCodeExt.DAO_EXCEPTION.getException("id不存在");
        }

        return super.removeById(id);
    }


    @Override
    public List<KnowledgeDO> getAllKnowledge() {
        List<Knowledge> knowledgelist = knowledgeMapper.selectList(new QueryWrapper<Knowledge>());
        List<KnowledgeDO> result = knowledgelist.stream()
                .map(knowledge -> {
                    KnowledgeDO knowledgeDO = new KnowledgeDO();
                    BeanUtil.copyProperties(knowledge, knowledgeDO);
                    return knowledgeDO;
                })
                .collect(Collectors.toList());
        return result;
    }

    @Override
    public Page<KnowledgeVO> getKnowledgePageList(KnowledgeQueryDTO knowledgeQueryDTO) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = setPageParam(
                knowledgeQueryDTO, OrderItem.desc("creation_datetime")
        );

        QueryWrapper<Knowledge> queryWrapper = new QueryWrapper<>();
        //存在
        queryWrapper.eq("usable", UsableEnum.ACTIVE.getCode());
        //id
        if (StringUtils.isNotEmpty(knowledgeQueryDTO.getKnowledgeId())) {
            queryWrapper.eq("knowledge_id", knowledgeQueryDTO.getKnowledgeId());
        }
        //知识点名
        if (StringUtils.isNotEmpty(knowledgeQueryDTO.getKnowledgeName())) {
            queryWrapper.like("knowledge_name", knowledgeQueryDTO.getKnowledgeName());
        }
        //知识点信息
        if (StringUtils.isNotEmpty(knowledgeQueryDTO.getKnowledgeIntroduce())) {
            queryWrapper.like("knowledge_introduce", knowledgeQueryDTO.getKnowledgeIntroduce());
        }
        //上级知识点id
        if (StringUtils.isNotEmpty(knowledgeQueryDTO.getKnowledgeSuperior())) {
            queryWrapper.eq("knowledge_superior", knowledgeQueryDTO.getKnowledgeSuperior());
        }
        //级别
        if (knowledgeQueryDTO.getLevel() != null) {
            queryWrapper.eq("level", knowledgeQueryDTO.getLevel());
        }
        //开始时间 创建
        if (knowledgeQueryDTO.getCreationDateOrigin() == null) {
            queryWrapper.ge("creation_datetime", knowledgeQueryDTO.getCreationDateOrigin());
        }
        //结束时间 创建
        if (knowledgeQueryDTO.getCreationDateTerminus() == null) {
            queryWrapper.le("creation_datetime", knowledgeQueryDTO.getCreationDateTerminus());
        }
        //组合条件
        IPage<Knowledge> entityPage = knowledgeMapper.selectPage(page, queryWrapper);
        List<KnowledgeVO> result = entityPage.getRecords().stream()
                .map(knowledge -> {
                    KnowledgeVO knowledgeVo = new KnowledgeVO();
                    BeanUtil.copyProperties(knowledge, knowledgeVo);
                    return knowledgeVo;
                })
                .collect(Collectors.toList());

        return Page.<KnowledgeVO>builder()
                .currPage(knowledgeQueryDTO.getPageNo())
                .pageSize(knowledgeQueryDTO.getPageSize())
                .totalCount((int) entityPage.getTotal())
                .list(result)
                .build();
    }


    @Override
    public boolean isExists(String key, String val, Serializable id) {
        QueryWrapper<Knowledge> qw = new QueryWrapper<>();
        qw.eq(key, val);
        if (id != null) {
            qw.ne("knowledge_id", id);
        }
        int num = this.count(qw);
        return num > 0;
    }

    /**
     * 判断知识点是否有全部存在
     * @param knowledgeDOS
     * @return
     */
    @Override
    public boolean isAllExists(List<KnowledgeDO> knowledgeDOS){
        if (knowledgeDOS==null||knowledgeDOS.size()<=0){
            return true;
        }
        //获取数据去重
        List<String> collect = knowledgeDOS.stream().map(
                knowledgeDO -> {
                    return knowledgeDO.getKnowledgeId();
                }
        ).distinct().collect(Collectors.toList());




        QueryWrapper<Knowledge> qw = new QueryWrapper<>();
        qw.in("knowledge_id",collect);
        List<Knowledge> list = this.list(qw);
        List<String> knowledgeCollect = list.stream().map(
                knowledge -> {
                    return knowledge.getKnowledgeId();
                }
        ).distinct().collect(Collectors.toList());

        if (knowledgeDOS.size()==knowledgeCollect.size()) {
            return true;
        }
        return false;
    }
    @Override
    public KnowledgeDO getKnowledgeById(String knowledgeId) {
        Knowledge byId = super.getById(knowledgeId);
        KnowledgeDO knowledgeDO = new KnowledgeDO(byId);
        return knowledgeDO;
    }

    @Override
    public KnowledgeDO getKnowledgeByName(String name) {
        /**
         * 参数检查
         */

        /**
         * 构建对象
         */
        Knowledge knowledge = knowledgeMapper.getKnowledgeByName(name);
        KnowledgeDO knowledgeDO = new KnowledgeDO(knowledge);

        return knowledgeDO;
    }

    @Override
    public KnowledgeDO treeKnowledge(String id) {
        /**
         * 参数检查
         */
        //id
        KnowledgeDO oldKnowledge = getKnowledgeById(id);

        if (oldKnowledge == null || StringUtils.isEmpty(oldKnowledge.getKnowledgeId())) {
            throw ReturnCodeExt.DAO_EXCEPTION.getException("id不存在");
        }
        /**
         * 生成树
         */
        oldKnowledge = knowledgeTree(oldKnowledge);

        return oldKnowledge;
    }

    @Override
    public List<KnowledgeDO> getKnowledgeByIds(List<String> collect) {
        if (CollUtil.isEmpty(collect)) {
            return null;
        }
        QueryWrapper<Knowledge> qw = new QueryWrapper<>();
        qw.in("knowledge_id", collect);
        List<Knowledge> list = super.list(qw);
        List<KnowledgeDO> collect1 = list.stream().map(knowledge -> new KnowledgeDO(knowledge)).collect(Collectors.toList());
        return collect1;
    }

    @Override
    public boolean checkKnowledgeChange(List<KnowledgeDO> knowledgeDOs, List<KnowledgeDO> oldKnowledgeDOs) {

        if (knowledgeDOs==oldKnowledgeDOs){
            return true;
        }
        if (knowledgeDOs.size()!=oldKnowledgeDOs.size()){
            return false;
        }
        List<String> collect = knowledgeDOs.stream().map(knowledgeDO -> {
            return knowledgeDO.getKnowledgeId();
        }).collect(Collectors.toList());
        for (KnowledgeDO oldKnowledgeDO : oldKnowledgeDOs) {
            if (!EqualsUtil.objectEquals(oldKnowledgeDO.getKnowledgeId(),collect)) {
                return false;
            }
        }
        return true;
    }


    /**
     * 获取子知识点
     */
    private KnowledgeDO childKnowledge(KnowledgeDO knowledgeDO) {
        /**
         * 获取子知识点
         */
        List<Knowledge> knowledges = knowledgeMapper.childKnowledge(knowledgeDO.getKnowledgeId());
        /**
         * 转换
         */
        knowledgeDO.setChilds(knowledges.stream().map(knowledge -> {
            return new KnowledgeDO(knowledge);
        }).collect(Collectors.toList()));

        return knowledgeDO;
    }


    /**
     * 递归生成树
     */
    private KnowledgeDO knowledgeTree(KnowledgeDO knowledgeDO) {
        if (knowledgeDO == null) {
            return null;
        }
        knowledgeDO = childKnowledge(knowledgeDO);
        List<KnowledgeDO> childs = knowledgeDO.getChilds();
        childs.forEach(knowledgeDO1 -> {
            knowledgeDO1 = knowledgeTree(knowledgeDO1);
        });
        return knowledgeDO;
    }

}

